package com.it2297.component;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.it2297.main.App;
import com.it2297.model.Comment;
import com.it2297.model.Product;

@SuppressWarnings("serial")
public abstract class Pagination<T> extends JPanel
{
	private final JButton firstBtn = new JButton("");
	private final JButton previousBtn = new JButton("");
	private final JTextField textField = new JTextField();
	private final JLabel label = new JLabel();
	private final JButton nextBtn = new JButton("");
	private final JButton lastBtn = new JButton("");
	private int lastPosition;
	private int count;
	private int position = 0;

	public Pagination(int count)
	{
		this.count = count;

		initControlGUI();

		refresh();
	}

	private void initControlGUI()
	{
		firstBtn.setIcon(new ImageIcon(App.class.getResource("/com/alee/extended/date/icons/previous_skip.png")));
		firstBtn.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				first();
			}

		});
		this.add(firstBtn);

		previousBtn.setIcon(new ImageIcon(App.class.getResource("/com/alee/extended/date/icons/previous.png")));
		previousBtn.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				previous();
			}
		});
		this.add(previousBtn);

		textField.setHorizontalAlignment(JTextField.CENTER);
		textField.setColumns(3);
		textField.addKeyListener(new KeyListener()
		{

			@Override
			public void keyPressed(KeyEvent arg0)
			{
				// Do nothing
			}

			@Override
			public void keyReleased(KeyEvent arg0)
			{
				if (arg0.getKeyCode() == KeyEvent.VK_ENTER)
				{
					try
					{
						goTo(Integer.parseInt(textField.getText()));
					}
					catch (Exception ex)
					{
						System.out.println("Illegal character.");
					}
					finally
					{
						arg0.getComponent().getParent().requestFocus();
					}

				}
				else if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE)
				{
					arg0.getComponent().getParent().requestFocus();
				}
			}

			@Override
			public void keyTyped(KeyEvent arg0)
			{
				// Do nothing
			}

		});
		textField.addFocusListener(new FocusListener()
		{

			@Override
			public void focusGained(FocusEvent arg0)
			{
				// Do nothing
			}

			@Override
			public void focusLost(FocusEvent arg0)
			{
				textField.setText(Integer.toString((getPosition() / getCount()) + 1));
			}

		});
		this.add(textField);

		label.setHorizontalAlignment(JLabel.CENTER);
		this.add(label);

		nextBtn.setIcon(new ImageIcon(App.class.getResource("/com/alee/extended/date/icons/next.png")));
		nextBtn.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				next();
			}

		});
		this.add(nextBtn);

		lastBtn.setIcon(new ImageIcon(App.class.getResource("/com/alee/extended/date/icons/next_skip.png")));
		lastBtn.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				last();
			}

		});
		this.add(lastBtn);
	}

	public void refresh()
	{
		lastPosition = getTotal() - 1;
		if (position > lastPosition)
		{
			last();
		}
		textField.setText((Integer.toString((position / count) + 1)));
		label.setText(" of " + (Integer.toString((lastPosition / count) + 1)));
	}

	private void next()
	{
		int _position = position + count;

		if (_position > lastPosition)
		{
			System.out.println("No more records.");
		}
		else
		{
			position = _position;
			action(subData(position, count));
			refresh();
		}

	}

	private void previous()
	{
		int _position = position - count;
		if (_position < 0)
		{
			System.out.println("No more records.");
		}
		else
		{
			position = _position;
			action(subData(position, count));
			refresh();
		}

	}

	private void first()
	{
		if (position == 0)
		{
			System.out.println("Already at first page.");
		}
		else
		{
			position = 0;
			action(subData(position, count));
			refresh();
		}
	}

	private void last()
	{
		if (position == lastPosition - (lastPosition % count))
		{
			System.out.println("Already at last page.");
		}
		else
		{
			position = lastPosition - (lastPosition % count);
			action(subData(position, count));
			refresh();
		}
	}

	private void goTo(int page)
	{
		int _position = count * (page - 1);

		if (_position > lastPosition)
		{
			System.out.println("Out of range.");
		}
		else if (_position < 0)
		{
			System.out.println("Invalid position.");
		}
		else
		{
			position = _position;
			action(subData(position, count));
			refresh();
		}
	}

	public int getPosition()
	{
		return position;
	}

	public int getCount()
	{
		return count;
	}

	protected abstract T subData(int position, int count);

	protected abstract void action(T data);

	protected abstract int getTotal();

}
